﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MockDataTransferObject;
using System.Data.SqlClient;
using MockCommon;
using System.Data;
using System.Collections.ObjectModel;

namespace MockDataAccess
{
    public class MessageDataAccess : BaseDataAccess<Message>
    {
        private Collection<SqlParameter> _parameters;

        /// <summary>
        /// Initializes a new instance of the <see cref="MessageDataAccess"/> class.
        /// </summary>
        public MessageDataAccess()
            : base()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="MessageDataAccess"/> class.
        /// </summary>
        /// <param name="isFake">if set to <c>true</c> [is fake].</param>
        public MessageDataAccess(bool isFake)
            : base(isFake)
        {
        }

        #region Is
        #endregion

        #region Get
        /// <summary>
        /// Gets the by to user id.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <returns></returns>
        public Collection<Message> GetByToUserId(Guid userId)
        {
            try
            {
                _parameters = new Collection<SqlParameter>();
                _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterUserId, Value = userId });

                DataTable dataTable = ExecuteQueryAsDataTable(Constant.MessageGetAllByToUserId, _parameters);
                Collection<AbstractEntity> entities = ConvertToList(dataTable, typeof(Message));
                return new Collection<Message>(entities.Cast<Message>().ToList());
            }
            catch (NullReferenceException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
            catch (ArgumentException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
            catch (InvalidCastException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
        }

        /// <summary>
        /// Gets the count by user id and is receive.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="isReceive">if set to <c>true</c> [is receive].</param>
        /// <returns></returns>
        public int GetCountByUserIdAndIsReceive(Guid userId, bool isReceive)
        {
            _parameters = new Collection<SqlParameter>();
            _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterUserId, Value = userId });
            _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterIsReceive, Value = isReceive });

            object value = ExecuteQueryAsScalar(Constant.MessageCountByToUserIdAndIsReceive, _parameters);
            if (value != null && value is int)
            {
                return (int)value;
            }
            return 0;
        }

        /// <summary>
        /// Gets the by user id and is receive.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="isReceive">if set to <c>true</c> [is receive].</param>
        /// <returns></returns>
        public Collection<Message> GetByUserIdAndIsReceive(Guid userId, bool isReceive)
        {
            try
            {
                _parameters = new Collection<SqlParameter>();
                _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterUserId, Value = userId });
                _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterIsReceive, Value = isReceive });

                DataTable dataTable = ExecuteQueryAsDataTable(Constant.MessageGetByToUserIdAndIsReceive, _parameters);
                Collection<AbstractEntity> entities = ConvertToList(dataTable, typeof(Message));
                return new Collection<Message>(entities.Cast<Message>().ToList());
            }
            catch (NullReferenceException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
            catch (ArgumentException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
            catch (InvalidCastException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
        }

        /// <summary>
        /// Gets the top by user id.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="top">The top.</param>
        /// <returns></returns>
        public Collection<Message> GetTopByUserId(Guid userId, int top)
        {
            try
            {
                _parameters = new Collection<SqlParameter>();
                _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterTop, Value = top });
                _parameters.Add(new SqlParameter { ParameterName = Constant.ParameterUserId, Value = userId });

                DataTable dataTable = ExecuteQueryAsDataTable(Constant.MessageGetTopByToUserId, _parameters);
                Collection<AbstractEntity> entities = ConvertToList(dataTable, typeof(Message));
                return new Collection<Message>(entities.Cast<Message>().ToList());
            }
            catch (NullReferenceException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
            catch (ArgumentException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
            catch (InvalidCastException exception)
            {
                throw new MockException(exception.Message, "DataAccess");
            }
        }
        #endregion
    }
}
